package com.geovis.emergency.spd.controller.pc;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.geovis.common.core.api.Result;
import com.geovis.emergency.spd.biz.pc.service.*;
import com.geovis.emergency.spd.biz.pc.wrapper.PcDrillDisasterEventWrapper;
import com.geovis.emergency.spd.biz.system.service.ISystemFileService;
import com.geovis.emergency.spd.entity.basic.entity.PcPunch;
import com.geovis.emergency.spd.entity.mobile.pojo.vo.PcDrillPlanTaskStatisticsVO;
import com.geovis.emergency.spd.entity.pc.entity.PcDrillDisasterEvent;
import com.geovis.emergency.spd.entity.pc.entity.PcDrillDutyOrg;
import com.geovis.emergency.spd.entity.pc.entity.PcDrillDutyUser;
import com.geovis.emergency.spd.entity.pc.entity.PcDrillPlanDetail;
import com.geovis.emergency.spd.entity.pc.pojo.enums.DisasterEventStatusEnum;
import com.geovis.emergency.spd.entity.pc.pojo.enums.StatusEnum;
import com.geovis.emergency.spd.entity.pc.pojo.vo.DrillStatisticsVO;
import com.geovis.emergency.spd.entity.pc.pojo.vo.PcDrillDisasterEventListVO;
import com.geovis.emergency.spd.entity.pc.pojo.vo.StatisticsEventVO;
import com.geovis.emergency.spd.entity.pc.pojo.vo.TaskTimeStatisticsVO;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Array;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 统计报告 控制器
 * </p>
 *
 * @author Lonsho
 * @version 1.0
 * @date 2022/6/30
 */
@RestController
@RequestMapping("/pc/statistics/report")
@RequiredArgsConstructor
@Api(value = "应急预案指挥模块 -  演练统计接口", tags = "应急预案指挥模块 -  演练统计报告接口")
@Slf4j
@Validated
public class StatisticsReportController {
    private final IPcDrillDisasterEventService pcDrillDisasterEventService;
    private final ISystemFileService systemFileService;

    private final IPcDrillDutyOrgService pcDrillDutyOrgService;

    private final IDrillStatisticsService drillStatisticsService;
    private final IPcDrillPlanDetailService pcDrillPlanDetailService;
    private final IPcDrillPlanTaskService pcDrillPlanTaskService;


    private final IPcDrillDutyUserService pcDrillDutyUserService;

    private final IPcPunchService pcPunchService;


    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "演练统计", notes = "演练统计接口")
    @PostMapping("drillStatistics/{pcDrillId}")
    public Result<DrillStatisticsVO> drillStatistics(@PathVariable String pcDrillId){

        return Result.ok(drillStatisticsService.drillStatistics(pcDrillId));
    }
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "演练任务用时", notes = "演练任务用时")
    @PostMapping("taskTime/{pcDrillId}")
    public Result<Map<String, Object>> taskTime(@PathVariable String pcDrillId, @ApiParam("演练灾害事件id") @RequestParam(value = "pcDrillDisasterId",required = false) String pcDrillDisasterId){
        List<PcDrillDutyOrg> dutyOrgList = pcDrillDutyOrgService.list(
                Wrappers.<PcDrillDutyOrg>lambdaQuery()
                        .eq(PcDrillDutyOrg::getPcDrillId, pcDrillId)
                        .ne(PcDrillDutyOrg::getOrgName,"工作组")
                        .orderByAsc(PcDrillDutyOrg::getIdx)
        );
//        List<TaskTimeStatisticsVO> taskTimeStatisticsList = pcDrillPlanTaskService.selectTimeStatistics(pcDrillId, pcDrillDisasterId);
//
//        List<String> nameList = Lists.newArrayList();
//        List<Map<String, Object>> dataList = Lists.newArrayList();
//        for (TaskTimeStatisticsVO taskTimeStatisticsVO : taskTimeStatisticsList) {
//            Map<String, Object> map = Maps.newHashMap();
//            map.put("type","line");
//            map.put("name",taskTimeStatisticsVO.getTitle());
//            List<Integer> data = Lists.newArrayList();
//            for (PcDrillDutyOrg pcDrillDutyOrg : dutyOrgList) {
//                Optional<TaskTimeStatisticsVO> first = taskTimeStatisticsList.stream().filter(s -> s.getGroupId().equals(pcDrillDutyOrg.getId()) && s.getTitle().equals(taskTimeStatisticsVO.getTitle())).findFirst();
//                if (first.isPresent()) {
//                    data.add(first.get().getTime());
//                    nameList.add(pcDrillDutyOrg.getOrgName());
//                }else {
//                    data.add(0);
//                }
//            }
//            map.put("data",data);
//            dataList.add(map);
//        }
        List<String> status= Arrays.asList("2","3");
        List<PcDrillPlanDetail> planDetails=pcDrillPlanDetailService.list( Wrappers.<PcDrillPlanDetail>lambdaQuery()
                .eq(PcDrillPlanDetail::getPcDrillId,pcDrillId)
        .in(PcDrillPlanDetail::getStatus,status));
        List<String> nameList = Lists.newArrayList();
        List<Map<String, Object>> dataList = Lists.newArrayList();
        for (int x=0;x<1;x++) {
            Map<String, Object> dataMap = Maps.newHashMap();
            dataMap.put("type","line");
            dataMap.put("name","时间");
            List<Integer> data = Lists.newArrayList();
            for (PcDrillPlanDetail detail : planDetails) {
                nameList.add(detail.getContent());
                data.add(detail.getSpendTime());
            }
            dataMap.put("data",data);
            dataList.add(dataMap);
        }

        Map<String, Object> resultMap = Maps.newHashMapWithExpectedSize(2);
        resultMap.put("nameList",nameList);
        resultMap.put("dataList",dataList);
        return Result.ok(resultMap);
    }
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "获取演练出勤情况", notes = "获取演练出勤情况")
    @PostMapping("attendance/{pcDrillId}")
    public Result<Map<String, Object>> attendance(@PathVariable String pcDrillId){
        List<PcDrillDutyOrg> dutyOrgList = pcDrillDutyOrgService.list(
                Wrappers.lambdaQuery(PcDrillDutyOrg.class)
                        .eq(PcDrillDutyOrg::getPcDrillId, pcDrillId)
                        .ne(PcDrillDutyOrg::getOrgName,"工作组")
                        .orderByAsc(PcDrillDutyOrg::getIdx)
        );


        List<String> nameList = Lists.newArrayList();
        List<Map<String, Object>> dataList = Lists.newArrayList();

        //组
        List<Integer> actual = Lists.newArrayList();
        List<Integer> absenteeism = Lists.newArrayList();
        for (PcDrillDutyOrg pcDrillDutyOrg : dutyOrgList) {
            nameList.add(pcDrillDutyOrg.getOrgName());
            //组下面所有的架构
//            List<PcDrillDutyOrg> groupList = dutyOrgList.stream().filter(s -> s.getAncestors().contains(pcDrillDutyOrg.getId())).collect(Collectors.toList());
//            Set<String> idList = groupList.stream().map(PcDrillDutyOrg::getId).collect(Collectors.toSet());
            List<String> idList=new ArrayList<>();
            idList.add(pcDrillDutyOrg.getId());
            //获取组所有的用户
            List<PcDrillDutyUser> dutyUserList = pcDrillDutyUserService.list(
                    Wrappers.<PcDrillDutyUser>lambdaQuery()
                            .isNotNull(PcDrillDutyUser::getPrincipalIds)
                            .in(PcDrillDutyUser::getPcDrillOrgId,idList)
                            .eq(PcDrillDutyUser::getPcDrillId, pcDrillId)
            );
            if (CollUtil.isNotEmpty(dutyUserList)){
                Set<String> userList = CollUtil.set(false);
                for (PcDrillDutyUser pcDrillDutyUser : dutyUserList) {
                    List<String> principalIdList = StrUtil.split(pcDrillDutyUser.getPrincipalIds(), ",");
                    userList.addAll(principalIdList);
                }
                //获取用户出勤情况
                List<PcPunch> punchList = pcPunchService.list(
                        Wrappers.lambdaQuery(PcPunch.class)
                                .eq(PcPunch::getPcDrillId,pcDrillId)
                                .eq(PcPunch::getSignInStatus, StatusEnum.TRUE.getCode())
                                .in(PcPunch::getPersonId, userList)
                );
                //出勤人数
                actual.add(punchList.size());
                //缺勤人数
                absenteeism.add(dutyUserList.size() - punchList.size());
            }else {
                actual.add(0);
                absenteeism.add(0);
            }
        }
        //实到
        Map<String, Object> series1 = Maps.newHashMapWithExpectedSize(5);
        series1.put("color","#29D68B");
        series1.put("stack","总计");
        series1.put("name","实到");
        series1.put("type","bar");
        series1.put("data",actual);
        dataList.add(series1);

        //缺席
        Map<String, Object> series2 = Maps.newHashMapWithExpectedSize(5);
        series2.put("color","#E65463");
        series2.put("stack","总计");
        series2.put("name","缺席");
        series2.put("type","bar");
        series2.put("data",absenteeism);
        dataList.add(series2);

        Map<String, Object> resultMap = Maps.newHashMapWithExpectedSize(2);
        resultMap.put("nameList",nameList);
        resultMap.put("dataList",dataList);
        return Result.ok(resultMap);
    }
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "获取演练所有的事件", notes = "获取演练所有的事件")
    @PostMapping("eventAll/{pcDrillId}")
    public Result<List<StatisticsEventVO>> eventAll(@PathVariable String pcDrillId){
        //指挥编组
        List<PcDrillDutyOrg> groupList = pcDrillDutyOrgService.list(
                Wrappers.<PcDrillDutyOrg>lambdaQuery()
                        .eq(PcDrillDutyOrg::getPcDrillId, pcDrillId)
                        .orderByAsc(PcDrillDutyOrg::getIdx)
        );
        List<PcDrillDisasterEventListVO> disasterEventList = pcDrillDisasterEventService.getList(pcDrillId,
                StrUtil.format("{},{}", DisasterEventStatusEnum.IN_PROGRESS.getCode(), DisasterEventStatusEnum.COMPLETED.getCode()));
        List<PcDrillDisasterEvent> eventList = disasterEventList.stream().map(s -> BeanUtil.toBean(s, PcDrillDisasterEvent.class)).collect(Collectors.toList());
        return Result.ok(PcDrillDisasterEventWrapper.build(systemFileService,pcDrillPlanDetailService,pcDrillPlanTaskService,groupList).listVO(eventList));
    }
}
